/*
 * Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;

import java.lang.annotation.Native;
import java.math.*;


/**
 * {@code Long} 类在对象中包装了一个基本类型 {@code long} 的值。
 * {@code Long} 类型的对象包含一个 {@code long} 类型的字段。
 *
 * <p>此外，该类提供了多个方法，用于将 {@code long} 转换为 {@code String}，
 * 将 {@code String} 转换为 {@code long}，以及处理 {@code long} 时有用的
 * 其他常量和方法。
 *
 * <p>实现注意事项："位操作"方法（如 {@link #highestOneBit(long) highestOneBit} 和
 * {@link #numberOfTrailingZeros(long) numberOfTrailingZeros}）的实现
 * 基于 Henry S. Warren, Jr. 的 <i>Hacker's Delight</i>（Addison Wesley, 2002）中的材料。
 *
 * @author  Lee Boynton
 * @author  Arthur van Hoff
 * @author  Josh Bloch
 * @author  Joseph D. Darcy
 * @since   JDK1.0
 */
public final class Long extends Number implements Comparable<Long> {
    /**
     * 保存 {@code long} 类型可以拥有的最小值的常量，-2<sup>63</sup>。
     */
    @Native public static final long MIN_VALUE = 0x8000000000000000L;

    /**
     * 保存 {@code long} 类型可以拥有的最大值的常量，2<sup>63</sup>-1。
     */
    @Native public static final long MAX_VALUE = 0x7fffffffffffffffL;

    /**
     * 表示基本类型 {@code long} 的 {@code Class} 实例。
     *
     * @since   JDK1.1
     */
    @SuppressWarnings("unchecked")
    public static final Class<Long>     TYPE = (Class<Long>) Class.getPrimitiveClass("long");

    /**
     * 返回第一个参数在第二个参数指定的基数中的字符串表示形式。
     *
     * <p>如果基数小于 {@code Character.MIN_RADIX} 或大于 {@code Character.MAX_RADIX}，
     * 则使用基数 {@code 10}。
     *
     * <p>如果第一个参数为负数，则结果的第一个元素是 ASCII 减号字符 {@code '-'}
     * ({@code '\u005Cu002d'})。如果第一个参数不是负数，则结果中不出现符号字符。
     *
     * <p>结果的其余字符表示第一个参数的大小。如果大小为零，则用单个零字符 {@code '0'}
     * ({@code '\u005Cu0030'}) 表示；否则，大小表示的第一个字符不会是零字符。
     * 以下 ASCII 字符用作数字：
     *
     * <blockquote>
     *   {@code 0123456789abcdefghijklmnopqrstuvwxyz}
     * </blockquote>
     *
     * 这些是从 {@code '\u005Cu0030'} 到 {@code '\u005Cu0039'} 和从 {@code '\u005Cu0061'}
     * 到 {@code '\u005Cu007a'}。如果 {@code radix} 是 <var>N</var>，则按所示顺序使用
     * 这些字符的前 <var>N</var> 个作为基数-<var>N</var> 数字。因此，十六进制（基数 16）
     * 的数字是 {@code 0123456789abcdef}。如果需要大写字母，可以对结果调用
     * {@link java.lang.String#toUpperCase()} 方法：
     *
     * <blockquote>
     *  {@code Long.toString(n, 16).toUpperCase()}
     * </blockquote>
     *
     * @param   i       要转换为字符串的 {@code long}。
     * @param   radix   字符串表示中使用的基数。
     * @return  指定基数中参数的字符串表示形式。
     * @see     java.lang.Character#MAX_RADIX
     * @see     java.lang.Character#MIN_RADIX
     */
    public static String toString(long i, int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;
        if (radix == 10)
            return toString(i);
        char[] buf = new char[65];
        int charPos = 64;
        boolean negative = (i < 0);

        if (!negative) {
            i = -i;
        }

        while (i <= -radix) {
            buf[charPos--] = Integer.digits[(int)(-(i % radix))];
            i = i / radix;
        }
        buf[charPos] = Integer.digits[(int)(-i)];

        if (negative) {
            buf[--charPos] = '-';
        }

        return new String(buf, charPos, (65 - charPos));
    }

    /**
     * 返回第一个参数作为无符号整数值在第二个参数指定的基数中的字符串表示形式。
     *
     * <p>如果基数小于 {@code Character.MIN_RADIX} 或大于 {@code Character.MAX_RADIX}，
     * 则使用基数 {@code 10}。
     *
     * <p>请注意，由于第一个参数被视为无符号值，因此不会打印前导符号字符。
     *
     * <p>如果大小为零，则用单个零字符 {@code '0'} ({@code '\u005Cu0030'}) 表示；
     * 否则，大小表示的第一个字符不会是零字符。
     *
     * <p>基数的行为和用作数字的字符与 {@link #toString(long, int) toString} 相同。
     *
     * @param   i       要转换为无符号字符串的整数。
     * @param   radix   字符串表示中使用的基数。
     * @return  指定基数中参数的无符号字符串表示形式。
     * @see     #toString(long, int)
     * @since 1.8
     */
    public static String toUnsignedString(long i, int radix) {
        if (i >= 0)
            return toString(i, radix);
        else {
            switch (radix) {
            case 2:
                return toBinaryString(i);

            case 4:
                return toUnsignedString0(i, 2);

            case 8:
                return toOctalString(i);

            case 10:
                /*
                 * We can get the effect of an unsigned division by 10
                 * on a long value by first shifting right, yielding a
                 * positive value, and then dividing by 5.  This
                 * allows the last digit and preceding digits to be
                 * isolated more quickly than by an initial conversion
                 * to BigInteger.
                 */
                long quot = (i >>> 1) / 5;
                long rem = i - quot * 10;
                return toString(quot) + rem;

            case 16:
                return toHexString(i);

            case 32:
                return toUnsignedString0(i, 5);

            default:
                return toUnsignedBigInteger(i).toString(radix);
            }
        }
    }

    /**
     * Return a BigInteger equal to the unsigned value of the
     * argument.
     */
    private static BigInteger toUnsignedBigInteger(long i) {
        if (i >= 0L)
            return BigInteger.valueOf(i);
        else {
            int upper = (int) (i >>> 32);
            int lower = (int) i;

            // return (upper << 32) + lower
            return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
                add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
        }
    }

    /**
     * 返回 {@code long} 参数作为无符号整数在十六进制（基数 16）中的字符串表示形式。
     *
     * <p>如果参数为负数，则无符号 {@code long} 值为参数加上 2<sup>64</sup>；
     * 否则等于参数。此值被转换为十六进制（基数 16）的 ASCII 数字字符串，
     * 没有额外的前导 {@code 0}。
     *
     * <p>可以通过调用 {@link Long#parseUnsignedLong(String, int) 
     * Long.parseUnsignedLong(s, 16)} 从返回的字符串 {@code s} 中恢复参数的值。
     *
     * <p>如果无符号大小为零，则用单个零字符 {@code '0'} ({@code '\u005Cu0030'}) 表示；
     * 否则，无符号大小表示的第一个字符不会是零字符。以下字符用作十六进制数字：
     *
     * <blockquote>
     *  {@code 0123456789abcdef}
     * </blockquote>
     *
     * 这些是从 {@code '\u005Cu0030'} 到 {@code '\u005Cu0039'} 和从 
     * {@code '\u005Cu0061'} 到 {@code '\u005Cu0066'} 的字符。如果需要大写字母，
     * 可以对结果调用 {@link java.lang.String#toUpperCase()} 方法：
     *
     * <blockquote>
     *  {@code Long.toHexString(n).toUpperCase()}
     * </blockquote>
     *
     * @param   i   要转换为字符串的 {@code long}。
     * @return  参数在十六进制（基数 16）中表示的无符号 {@code long} 值的字符串表示形式。
     * @see #parseUnsignedLong(String, int)
     * @see #toUnsignedString(long, int)
     * @since   JDK 1.0.2
     */
    public static String toHexString(long i) {
        return toUnsignedString0(i, 4);
    }

    /**
     * 返回 {@code long} 参数作为无符号整数在八进制（基数 8）中的字符串表示形式。
     *
     * <p>如果参数为负数，则无符号 {@code long} 值为参数加上 2<sup>64</sup>；
     * 否则等于参数。此值被转换为八进制（基数 8）的 ASCII 数字字符串，
     * 没有额外的前导 {@code 0}。
     *
     * <p>可以通过调用 {@link Long#parseUnsignedLong(String, int) 
     * Long.parseUnsignedLong(s, 8)} 从返回的字符串 {@code s} 中恢复参数的值。
     *
     * <p>如果无符号大小为零，则用单个零字符 {@code '0'} ({@code '\u005Cu0030'}) 表示；
     * 否则，无符号大小表示的第一个字符不会是零字符。以下字符用作八进制数字：
     *
     * <blockquote>
     *  {@code 01234567}
     * </blockquote>
     *
     * 这些是从 {@code '\u005Cu0030'} 到 {@code '\u005Cu0037'} 的字符。
     *
     * @param   i   要转换为字符串的 {@code long}。
     * @return  参数在八进制（基数 8）中表示的无符号 {@code long} 值的字符串表示形式。
     * @see #parseUnsignedLong(String, int)
     * @see #toUnsignedString(long, int)
     * @since   JDK 1.0.2
     */
    public static String toOctalString(long i) {
        return toUnsignedString0(i, 3);
    }

    /**
     * 返回 {@code long} 参数作为无符号整数在二进制（基数 2）中的字符串表示形式。
     *
     * <p>如果参数为负数，则无符号 {@code long} 值为参数加上 2<sup>64</sup>；
     * 否则等于参数。此值被转换为二进制（基数 2）的 ASCII 数字字符串，
     * 没有额外的前导 {@code 0}。
     *
     * <p>可以通过调用 {@link Long#parseUnsignedLong(String, int) 
     * Long.parseUnsignedLong(s, 2)} 从返回的字符串 {@code s} 中恢复参数的值。
     *
     * <p>如果无符号大小为零，则用单个零字符 {@code '0'} ({@code '\u005Cu0030'}) 表示；
     * 否则，无符号大小表示的第一个字符不会是零字符。字符 {@code '0'} 
     * ({@code '\u005Cu0030'}) 和 {@code '1'} ({@code '\u005Cu0031'}) 用作二进制数字。
     *
     * @param   i   要转换为字符串的 {@code long}。
     * @return  参数在二进制（基数 2）中表示的无符号 {@code long} 值的字符串表示形式。
     * @see #parseUnsignedLong(String, int)
     * @see #toUnsignedString(long, int)
     * @since   JDK 1.0.2
     */
    public static String toBinaryString(long i) {
        return toUnsignedString0(i, 1);
    }

    /**
     * 将长整型（作为无符号处理）格式化为字符串。
     * @param val 要格式化的值
     * @param shift 格式化基数的对数（十六进制为4，八进制为3，二进制为1）
     */
    static String toUnsignedString0(long val, int shift) {
        // assert shift > 0 && shift <=5 : "Illegal shift value";
        int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
        int chars = Math.max(((mag + (shift - 1)) / shift), 1);
        char[] buf = new char[chars];

        formatUnsignedLong(val, shift, buf, 0, chars);
        return new String(buf, true);
    }

    /**
     * 将长整型（作为无符号处理）格式化到字符缓冲区中。
     * @param val 要格式化的无符号长整型
     * @param shift 格式化基数的对数（十六进制为4，八进制为3，二进制为1）
     * @param buf 要写入的字符缓冲区
     * @param offset 目标缓冲区中开始的偏移量
     * @param len 要写入的字符数
     * @return 使用的最低字符位置
     */
     static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
        int charPos = len;
        int radix = 1 << shift;
        int mask = radix - 1;
        do {
            buf[offset + --charPos] = Integer.digits[((int) val) & mask];
            val >>>= shift;
        } while (val != 0 && charPos > 0);

        return charPos;
    }

    /**
     * 返回表示指定 {@code long} 的 {@code String} 对象。参数被转换为
     * 有符号十进制表示并作为字符串返回，就像将参数和基数 10 作为参数
     * 传递给 {@link #toString(long, int)} 方法一样。
     *
     * @param   i   要转换的 {@code long}。
     * @return  参数在十进制中的字符串表示形式。
     */
    public static String toString(long i) {
        if (i == Long.MIN_VALUE)
            return "-9223372036854775808";
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        getChars(i, size, buf);
        return new String(buf, true);
    }

    /**
     * 返回参数作为无符号十进制值的字符串表示形式。
     *
     * 参数被转换为无符号十进制表示并作为字符串返回，就像将参数和基数 10
     * 作为参数传递给 {@link #toUnsignedString(long, int)} 方法一样。
     *
     * @param   i  要转换为无符号字符串的整数。
     * @return  参数的无符号字符串表示形式。
     * @see     #toUnsignedString(long, int)
     * @since 1.8
     */
    public static String toUnsignedString(long i) {
        return toUnsignedString(i, 10);
    }

    /**
     * 将表示整数 i 的字符放入字符数组 buf 中。字符从指定索引（不包括）
     * 的最低有效数字开始反向放入缓冲区，然后从那里向后工作。
     *
     * 如果 i == Long.MIN_VALUE 将失败
     */
    static void getChars(long i, int index, char[] buf) {
        long q;
        int r;
        int charPos = index;
        char sign = 0;

        if (i < 0) {
            sign = '-';
            i = -i;
        }

        // Get 2 digits/iteration using longs until quotient fits into an int
        while (i > Integer.MAX_VALUE) {
            q = i / 100;
            // really: r = i - (q * 100);
            r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
            i = q;
            buf[--charPos] = Integer.DigitOnes[r];
            buf[--charPos] = Integer.DigitTens[r];
        }

        // Get 2 digits/iteration using ints
        int q2;
        int i2 = (int)i;
        while (i2 >= 65536) {
            q2 = i2 / 100;
            // really: r = i2 - (q * 100);
            r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
            i2 = q2;
            buf[--charPos] = Integer.DigitOnes[r];
            buf[--charPos] = Integer.DigitTens[r];
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i2 <= 65536, i2);
        for (;;) {
            q2 = (i2 * 52429) >>> (16+3);
            r = i2 - ((q2 << 3) + (q2 << 1));  // r = i2-(q2*10) ...
            buf[--charPos] = Integer.digits[r];
            i2 = q2;
            if (i2 == 0) break;
        }
        if (sign != 0) {
            buf[--charPos] = sign;
        }
    }

    // Requires positive x
    static int stringSize(long x) {
        long p = 10;
        for (int i=1; i<19; i++) {
            if (x < p)
                return i;
            p = 10*p;
        }
        return 19;
    }

    /**
     * 将字符串参数解析为第二个参数指定基数中的有符号 {@code long}。
     * 字符串中的字符必须都是指定基数的数字（由 {@link java.lang.Character#digit(char, int)}
     * 是否返回非负值确定），除了第一个字符可以是 ASCII 减号 {@code '-'} 
     * ({@code '\u005Cu002D'}) 来表示负值，或者 ASCII 加号 {@code '+'}
     * ({@code '\u005Cu002B'}) 来表示正值。返回结果 {@code long} 值。
     *
     * <p>注意，字符 {@code L} ({@code '\u005Cu004C'}) 和 {@code l}
     * ({@code '\u005Cu006C'}) 都不允许出现在字符串末尾作为类型指示符，
     * 尽管在 Java 编程语言源代码中是允许的 - 除非 {@code L} 或 {@code l}
     * 可以作为基数大于或等于 22 的数字出现。
     *
     * <p>如果出现以下任何情况，将抛出 {@code NumberFormatException} 类型的异常：
     * <ul>
     *
     * <li>第一个参数为 {@code null} 或长度为零的字符串。
     *
     * <li>{@code radix} 小于 {@link java.lang.Character#MIN_RADIX} 
     * 或大于 {@link java.lang.Character#MAX_RADIX}。
     *
     * <li>字符串的任何字符都不是指定基数的数字，除了第一个字符可以是减号
     * {@code '-'} ({@code '\u005Cu002d'}) 或加号 {@code '+'} 
     * ({@code '\u005Cu002B'})，前提是字符串长度大于 1。
     *
     * <li>字符串表示的值不是 {@code long} 类型的值。
     * </ul>
     *
     * <p>示例：
     * <blockquote><pre>
     * parseLong("0", 10) 返回 0L
     * parseLong("473", 10) 返回 473L
     * parseLong("+42", 10) 返回 42L
     * parseLong("-0", 10) 返回 0L
     * parseLong("-FF", 16) 返回 -255L
     * parseLong("1100110", 2) 返回 102L
     * parseLong("99", 8) 抛出 NumberFormatException
     * parseLong("Hazelnut", 10) 抛出 NumberFormatException
     * parseLong("Hazelnut", 36) 返回 1356099454469L
     * </pre></blockquote>
     *
     * @param      s       包含要解析的 {@code long} 表示的 {@code String}。
     * @param      radix   解析 {@code s} 时使用的基数。
     * @return     字符串参数在指定基数中表示的 {@code long}。
     * @throws     NumberFormatException  如果字符串不包含可解析的 {@code long}。
     */
    public static long parseLong(String s, int radix)
              throws NumberFormatException
    {
        if (s == null) {
            throw new NumberFormatException("null");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }
        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        long result = 0;
        boolean negative = false;
        int i = 0, len = s.length();
        long limit = -Long.MAX_VALUE;
        long multmin;
        int digit;

        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Long.MIN_VALUE;
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);

                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            multmin = limit / radix;
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        return negative ? result : -result;
    }

    /**
     * 将字符串参数解析为有符号的十进制 {@code long}。
     * 字符串中的字符必须都是十进制数字，除了第一个字符可以是
     * ASCII减号 {@code '-'} ({@code \u005Cu002D'}) 来表示负值，
     * 或者ASCII加号 {@code '+'} ({@code '\u005Cu002B'}) 来表示正值。
     * 返回结果 {@code long} 值，就像将参数和基数 {@code 10}
     * 作为参数传递给 {@link #parseLong(java.lang.String, int)} 方法一样。
     *
     * <p>注意，字符 {@code L} ({@code '\u005Cu004C'}) 和 {@code l}
     * ({@code '\u005Cu006C'}) 都不允许出现在字符串末尾作为类型指示符，
     * 尽管在Java编程语言源代码中是允许的。
     *
     * @param      s   包含要解析的 {@code long} 表示的 {@code String}
     * @return     参数以十进制表示的 {@code long}。
     * @throws     NumberFormatException  如果字符串不包含可解析的 {@code long}。
     */
    public static long parseLong(String s) throws NumberFormatException {
        return parseLong(s, 10);
    }

    /**
     * Parses the string argument as an unsigned {@code long} in the
     * radix specified by the second argument.  An unsigned integer
     * maps the values usually associated with negative numbers to
     * positive numbers larger than {@code MAX_VALUE}.
     *
     * The characters in the string must all be digits of the
     * specified radix (as determined by whether {@link
     * java.lang.Character#digit(char, int)} returns a nonnegative
     * value), except that the first character may be an ASCII plus
     * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting
     * integer value is returned.
     *
     * <p>An exception of type {@code NumberFormatException} is
     * thrown if any of the following situations occurs:
     * <ul>
     * <li>The first argument is {@code null} or is a string of
     * length zero.
     *
     * <li>The radix is either smaller than
     * {@link java.lang.Character#MIN_RADIX} or
     * larger than {@link java.lang.Character#MAX_RADIX}.
     *
     * <li>Any character of the string is not a digit of the specified
     * radix, except that the first character may be a plus sign
     * {@code '+'} ({@code '\u005Cu002B'}) provided that the
     * string is longer than length 1.
     *
     * <li>The value represented by the string is larger than the
     * largest unsigned {@code long}, 2<sup>64</sup>-1.
     *
     * </ul>
     *
     *
     * @param      s   the {@code String} containing the unsigned integer
     *                  representation to be parsed
     * @param      radix   the radix to be used while parsing {@code s}.
     * @return     the unsigned {@code long} represented by the string
     *             argument in the specified radix.
     * @throws     NumberFormatException if the {@code String}
     *             does not contain a parsable {@code long}.
     * @since 1.8
     */
    public static long parseUnsignedLong(String s, int radix)
                throws NumberFormatException {
        if (s == null)  {
            throw new NumberFormatException("null");
        }

        int len = s.length();
        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar == '-') {
                throw new
                    NumberFormatException(String.format("Illegal leading minus sign " +
                                                       "on unsigned string %s.", s));
            } else {
                if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
                    (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits
                    return parseLong(s, radix);
                }

                // No need for range checks on len due to testing above.
                long first = parseLong(s.substring(0, len - 1), radix);
                int second = Character.digit(s.charAt(len - 1), radix);
                if (second < 0) {
                    throw new NumberFormatException("Bad digit at end of " + s);
                }
                long result = first * radix + second;
                if (compareUnsigned(result, first) < 0) {
                    /*
                     * The maximum unsigned value, (2^64)-1, takes at
                     * most one more digit to represent than the
                     * maximum signed value, (2^63)-1.  Therefore,
                     * parsing (len - 1) digits will be appropriately
                     * in-range of the signed parsing.  In other
                     * words, if parsing (len -1) digits overflows
                     * signed parsing, parsing len digits will
                     * certainly overflow unsigned parsing.
                     *
                     * The compareUnsigned check above catches
                     * situations where an unsigned overflow occurs
                     * incorporating the contribution of the final
                     * digit.
                     */
                    throw new NumberFormatException(String.format("String value %s exceeds " +
                                                                  "range of unsigned long.", s));
                }
                return result;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
    }

    /**
     * 将字符串参数解析为无符号十进制 {@code long}。字符串中的字符必须都是
     * 十进制数字，除了第一个字符可以是 ASCII 加号 {@code '+'} 
     * ({@code '\u005Cu002B'})。返回结果整数值，就像将参数和基数 10
     * 作为参数传递给 {@link #parseUnsignedLong(java.lang.String, int)} 方法一样。
     *
     * @param s   包含要解析的无符号 {@code long} 表示的 {@code String}
     * @return    十进制字符串参数表示的无符号 {@code long} 值
     * @throws    NumberFormatException  如果字符串不包含可解析的无符号整数。
     * @since 1.8
     */
    public static long parseUnsignedLong(String s) throws NumberFormatException {
        return parseUnsignedLong(s, 10);
    }

    /**
     * 返回一个 {@code Long} 对象，该对象保存从指定 {@code String} 中提取的值，
     * 使用第二个参数给定的基数进行解析。第一个参数被解释为表示第二个参数
     * 指定基数中的有符号 {@code long}，就像将参数传递给 
     * {@link #parseLong(java.lang.String, int)} 方法一样。结果是一个
     * 表示字符串指定的 {@code long} 值的 {@code Long} 对象。
     *
     * <p>换句话说，此方法返回一个等于以下值的 {@code Long} 对象：
     *
     * <blockquote>
     *  {@code new Long(Long.parseLong(s, radix))}
     * </blockquote>
     *
     * @param      s       要解析的字符串
     * @param      radix   解释 {@code s} 时使用的基数
     * @return     保存字符串参数在指定基数中表示的值的 {@code Long} 对象。
     * @throws     NumberFormatException  如果 {@code String} 不包含可解析的 {@code long}。
     */
    public static Long valueOf(String s, int radix) throws NumberFormatException {
        return Long.valueOf(parseLong(s, radix));
    }

    /**
     * 返回保存指定 {@code String} 值的 {@code Long} 对象。参数被解释为
     * 表示有符号十进制 {@code long}，就像将参数传递给 
     * {@link #parseLong(java.lang.String)} 方法一样。结果是一个表示
     * 字符串指定的整数值的 {@code Long} 对象。
     *
     * <p>换句话说，此方法返回一个等于以下值的 {@code Long} 对象：
     *
     * <blockquote>
     *  {@code new Long(Long.parseLong(s))}
     * </blockquote>
     *
     * @param      s   要解析的字符串。
     * @return     保存字符串参数表示的值的 {@code Long} 对象。
     * @throws     NumberFormatException  如果字符串无法解析为 {@code long}。
     */
    public static Long valueOf(String s) throws NumberFormatException
    {
        return Long.valueOf(parseLong(s, 10));
    }

    private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }

    /**
     * 返回表示指定 {@code long} 值的 {@code Long} 实例。
     * 如果不需要新的 {@code Long} 实例，通常应优先使用此方法而不是构造函数
     * {@link #Long(long)}，因为此方法通过缓存频繁请求的值，
     * 可能会产生明显更好的空间和时间性能。
     *
     * 注意，与 {@code Integer} 类中的 {@linkplain Integer#valueOf(int)
     * 对应方法} 不同，此方法<em>不</em>要求缓存特定范围内的值。
     *
     * @param  l 长整型值。
     * @return 表示 {@code l} 的 {@code Long} 实例。
     * @since  1.5
     */
    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

    /**
     * 将 {@code String} 解码为 {@code Long}。
     * 接受由以下语法给出的十进制、十六进制和八进制数字：
     *
     * <blockquote>
     * <dl>
     * <dt><i>可解码字符串:</i>
     * <dd><i>符号<sub>可选</sub> 十进制数字</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0x} <i>十六进制数字</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0X} <i>十六进制数字</i>
     * <dd><i>符号<sub>可选</sub></i> {@code #} <i>十六进制数字</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0} <i>八进制数字</i>
     *
     * <dt><i>符号:</i>
     * <dd>{@code -}
     * <dd>{@code +}
     * </dl>
     * </blockquote>
     *
     * <i>十进制数字</i>、<i>十六进制数字</i> 和 <i>八进制数字</i>
     * 如 <cite>Java&trade; 语言规范</cite> 第 3.10.1 节中定义，
     * 除了数字之间不接受下划线。
     *
     * <p>跟在可选符号和/或基数说明符（"{@code 0x}"、"{@code 0X}"、
     * "{@code #}" 或前导零）后面的字符序列由 {@code Long.parseLong} 方法
     * 使用指示的基数（10、16 或 8）进行解析。此字符序列必须表示正值，
     * 否则将抛出 {@link NumberFormatException}。如果指定 {@code String} 
     * 的第一个字符是减号，则结果被取反。{@code String} 中不允许有空白字符。
     *
     * @param     nm 要解码的 {@code String}。
     * @return    保存 {@code nm} 表示的 {@code long} 值的 {@code Long} 对象
     * @throws    NumberFormatException  如果 {@code String} 不包含可解析的 {@code long}。
     * @see java.lang.Long#parseLong(String, int)
     * @since 1.2
     */
    public static Long decode(String nm) throws NumberFormatException {
        int radix = 10;
        int index = 0;
        boolean negative = false;
        Long result;

        if (nm.isEmpty())
            throw new NumberFormatException("Zero length string");
        char firstChar = nm.charAt(0);
        // Handle sign, if present
        if (firstChar == '-') {
            negative = true;
            index++;
        } else if (firstChar == '+')
            index++;

        // Handle radix specifier, if present
        if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
            index += 2;
            radix = 16;
        }
        else if (nm.startsWith("#", index)) {
            index ++;
            radix = 16;
        }
        else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
            index ++;
            radix = 8;
        }

        if (nm.startsWith("-", index) || nm.startsWith("+", index))
            throw new NumberFormatException("Sign character in wrong position");

        try {
            result = Long.valueOf(nm.substring(index), radix);
            result = negative ? Long.valueOf(-result.longValue()) : result;
        } catch (NumberFormatException e) {
            // If number is Long.MIN_VALUE, we'll end up here. The next line
            // handles this case, and causes any genuine format error to be
            // rethrown.
            String constant = negative ? ("-" + nm.substring(index))
                                       : nm.substring(index);
            result = Long.valueOf(constant, radix);
        }
        return result;
    }

    /**
     * {@code Long} 的值。
     *
     * @serial
     */
    private final long value;

    /**
     * 构造一个新分配的 {@code Long} 对象，表示指定的 {@code long} 参数。
     *
     * @param   value   {@code Long} 对象要表示的值。
     */
    public Long(long value) {
        this.value = value;
    }

    /**
     * 构造一个新分配的 {@code Long} 对象，表示 {@code String} 参数
     * 指示的 {@code long} 值。字符串被转换为 {@code long} 值，
     * 转换方式与 {@code parseLong} 方法对基数 10 使用的方式完全相同。
     *
     * @param      s   要转换为 {@code Long} 的 {@code String}。
     * @throws     NumberFormatException  如果 {@code String} 不包含可解析的 {@code long}。
     * @see        java.lang.Long#parseLong(java.lang.String, int)
     */
    public Long(String s) throws NumberFormatException {
        this.value = parseLong(s, 10);
    }

    /**
     * 在窄化基本类型转换后，返回此 {@code Long} 的值作为 {@code byte}。
     * @jls 5.1.3 窄化基本类型转换
     */
    public byte byteValue() {
        return (byte)value;
    }

    /**
     * 在窄化基本类型转换后，返回此 {@code Long} 的值作为 {@code short}。
     * @jls 5.1.3 窄化基本类型转换
     */
    public short shortValue() {
        return (short)value;
    }

    /**
     * 在窄化基本类型转换后，返回此 {@code Long} 的值作为 {@code int}。
     * @jls 5.1.3 窄化基本类型转换
     */
    public int intValue() {
        return (int)value;
    }

    /**
     * 返回此 {@code Long} 的值作为 {@code long} 值。
     */
    public long longValue() {
        return value;
    }

    /**
     * 在扩展基本类型转换后，返回此 {@code Long} 的值作为 {@code float}。
     * @jls 5.1.2 扩展基本类型转换
     */
    public float floatValue() {
        return (float)value;
    }

    /**
     * 在扩展基本类型转换后，返回此 {@code Long} 的值作为 {@code double}。
     * @jls 5.1.2 扩展基本类型转换
     */
    public double doubleValue() {
        return (double)value;
    }

    /**
     * 返回表示此 {@code Long} 值的 {@code String} 对象。值被转换为
     * 有符号十进制表示并作为字符串返回，就像将 {@code long} 值作为参数
     * 传递给 {@link java.lang.Long#toString(long)} 方法一样。
     *
     * @return  此对象的值在十进制中的字符串表示形式。
     */
    public String toString() {
        return toString(value);
    }

    /**
     * Returns a hash code for this {@code Long}. The result is
     * the exclusive OR of the two halves of the primitive
     * {@code long} value held by this {@code Long}
     * object. That is, the hashcode is the value of the expression:
     *
     * <blockquote>
     *  {@code (int)(this.longValue()^(this.longValue()>>>32))}
     * </blockquote>
     *
     * @return  a hash code value for this object.
     */
    @Override
    public int hashCode() {
        return Long.hashCode(value);
    }

    /**
     * Returns a hash code for a {@code long} value; compatible with
     * {@code Long.hashCode()}.
     *
     * @param value the value to hash
     * @return a hash code value for a {@code long} value.
     * @since 1.8
     */
    public static int hashCode(long value) {
        return (int)(value ^ (value >>> 32));
    }

    /**
     * Compares this object to the specified object.  The result is
     * {@code true} if and only if the argument is not
     * {@code null} and is a {@code Long} object that
     * contains the same {@code long} value as this object.
     *
     * @param   obj   the object to compare with.
     * @return  {@code true} if the objects are the same;
     *          {@code false} otherwise.
     */
    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }

    /**
     * Determines the {@code long} value of the system property
     * with the specified name.
     *
     * <p>The first argument is treated as the name of a system
     * property.  System properties are accessible through the {@link
     * java.lang.System#getProperty(java.lang.String)} method. The
     * string value of this property is then interpreted as a {@code
     * long} value using the grammar supported by {@link Long#decode decode}
     * and a {@code Long} object representing this value is returned.
     *
     * <p>If there is no property with the specified name, if the
     * specified name is empty or {@code null}, or if the property
     * does not have the correct numeric format, then {@code null} is
     * returned.
     *
     * <p>In other words, this method returns a {@code Long} object
     * equal to the value of:
     *
     * <blockquote>
     *  {@code getLong(nm, null)}
     * </blockquote>
     *
     * @param   nm   property name.
     * @return  the {@code Long} value of the property.
     * @throws  SecurityException for the same reasons as
     *          {@link System#getProperty(String) System.getProperty}
     * @see     java.lang.System#getProperty(java.lang.String)
     * @see     java.lang.System#getProperty(java.lang.String, java.lang.String)
     */
    public static Long getLong(String nm) {
        return getLong(nm, null);
    }

    /**
     * Determines the {@code long} value of the system property
     * with the specified name.
     *
     * <p>The first argument is treated as the name of a system
     * property.  System properties are accessible through the {@link
     * java.lang.System#getProperty(java.lang.String)} method. The
     * string value of this property is then interpreted as a {@code
     * long} value using the grammar supported by {@link Long#decode decode}
     * and a {@code Long} object representing this value is returned.
     *
     * <p>The second argument is the default value. A {@code Long} object
     * that represents the value of the second argument is returned if there
     * is no property of the specified name, if the property does not have
     * the correct numeric format, or if the specified name is empty or null.
     *
     * <p>In other words, this method returns a {@code Long} object equal
     * to the value of:
     *
     * <blockquote>
     *  {@code getLong(nm, new Long(val))}
     * </blockquote>
     *
     * but in practice it may be implemented in a manner such as:
     *
     * <blockquote><pre>
     * Long result = getLong(nm, null);
     * return (result == null) ? new Long(val) : result;
     * </pre></blockquote>
     *
     * to avoid the unnecessary allocation of a {@code Long} object when
     * the default value is not needed.
     *
     * @param   nm    property name.
     * @param   val   default value.
     * @return  the {@code Long} value of the property.
     * @throws  SecurityException for the same reasons as
     *          {@link System#getProperty(String) System.getProperty}
     * @see     java.lang.System#getProperty(java.lang.String)
     * @see     java.lang.System#getProperty(java.lang.String, java.lang.String)
     */
    public static Long getLong(String nm, long val) {
        Long result = Long.getLong(nm, null);
        return (result == null) ? Long.valueOf(val) : result;
    }

    /**
     * Returns the {@code long} value of the system property with
     * the specified name.  The first argument is treated as the name
     * of a system property.  System properties are accessible through
     * the {@link java.lang.System#getProperty(java.lang.String)}
     * method. The string value of this property is then interpreted
     * as a {@code long} value, as per the
     * {@link Long#decode decode} method, and a {@code Long} object
     * representing this value is returned; in summary:
     *
     * <ul>
     * <li>If the property value begins with the two ASCII characters
     * {@code 0x} or the ASCII character {@code #}, not followed by
     * a minus sign, then the rest of it is parsed as a hexadecimal integer
     * 就像使用基数 16 的 {@link #valueOf(java.lang.String, int)} 方法一样。
     * <li>如果属性值以 ASCII 字符 {@code 0} 开头，后跟另一个字符，
     * 则将其解析为八进制整数，就像使用基数 8 的 {@link #valueOf(java.lang.String, int)} 方法一样。
     * <li>否则，属性值被解析为十进制整数，就像使用基数 10 的
     * {@link #valueOf(java.lang.String, int)} 方法一样。
     * </ul>
     *
     * <p>请注意，在任何情况下，都不允许 {@code L} ({@code '\u005Cu004C'}) 或 {@code l}
     * ({@code '\u005Cu006C'}) 出现在属性值的末尾作为类型指示符，
     * 尽管在 Java 编程语言源代码中是允许的。
     *
     * <p>第二个参数是默认值。如果没有指定名称的属性，如果属性没有正确的数字格式，
     * 或者如果指定的名称为空或 {@code null}，则返回默认值。
     *
     * @param   nm   属性名称。
     * @param   val   默认值。
     * @return  属性的 {@code Long} 值。
     * @throws  SecurityException 原因与 {@link System#getProperty(String) System.getProperty} 相同
     * @see     System#getProperty(java.lang.String)
     * @see     System#getProperty(java.lang.String, java.lang.String)
     */
    public static Long getLong(String nm, Long val) {
        String v = null;
        try {
            v = System.getProperty(nm);
        } catch (IllegalArgumentException | NullPointerException e) {
        }
        if (v != null) {
            try {
                return Long.decode(v);
            } catch (NumberFormatException e) {
            }
        }
        return val;
    }

    /**
     * 数值比较两个 {@code Long} 对象。
     *
     * @param   anotherLong   要比较的 {@code Long}。
     * @return  如果此 {@code Long} 等于参数 {@code Long}，则返回值 {@code 0}；
     *          如果此 {@code Long} 在数值上小于参数 {@code Long}，则返回小于 {@code 0} 的值；
     *          如果此 {@code Long} 在数值上大于参数 {@code Long}，则返回大于 {@code 0} 的值
     *          （有符号比较）。
     * @since   1.2
     */
    public int compareTo(Long anotherLong) {
        return compare(this.value, anotherLong.value);
    }

    /**
     * 数值比较两个 {@code long} 值。
     * 返回的值与以下代码返回的值相同：
     * <pre>
     *    Long.valueOf(x).compareTo(Long.valueOf(y))
     * </pre>
     *
     * @param  x 要比较的第一个 {@code long}
     * @param  y 要比较的第二个 {@code long}
     * @return 如果 {@code x == y}，则返回值 {@code 0}；
     *         如果 {@code x < y}，则返回小于 {@code 0} 的值；
     *         如果 {@code x > y}，则返回大于 {@code 0} 的值
     * @since 1.7
     */
    public static int compare(long x, long y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

    /**
     * 将值视为无符号数值比较两个 {@code long} 值。
     *
     * @param  x 要比较的第一个 {@code long}
     * @param  y 要比较的第二个 {@code long}
     * @return 如果 {@code x == y}，则返回值 {@code 0}；
     *         如果作为无符号值 {@code x < y}，则返回小于 {@code 0} 的值；
     *         如果作为无符号值 {@code x > y}，则返回大于 {@code 0} 的值
     * @since 1.8
     */
    public static int compareUnsigned(long x, long y) {
        return compare(x + MIN_VALUE, y + MIN_VALUE);
    }


    /**
     * 返回第一个参数除以第二个参数的无符号商，其中每个参数和结果都被解释为无符号值。
     *
     * <p>请注意，在二进制补码算术中，如果两个操作数都被视为有符号或都被视为无符号，
     * 则其他三个基本算术运算（加法、减法和乘法）在位级别上是相同的。
     * 因此不提供单独的 {@code addUnsigned} 等方法。
     *
     * @param dividend 被除数
     * @param divisor 除数
     * @return 第一个参数除以第二个参数的无符号商
     * @see #remainderUnsigned
     * @since 1.8
     */
    public static long divideUnsigned(long dividend, long divisor) {
        if (divisor < 0L) { // signed comparison
            // Answer must be 0 or 1 depending on relative magnitude
            // of dividend and divisor.
            return (compareUnsigned(dividend, divisor)) < 0 ? 0L :1L;
        }

        if (dividend > 0) //  Both inputs non-negative
            return dividend/divisor;
        else {
            /*
             * For simple code, leveraging BigInteger.  Longer and faster
             * code written directly in terms of operations on longs is
             * possible; see "Hacker's Delight" for divide and remainder
             * algorithms.
             */
            return toUnsignedBigInteger(dividend).
                divide(toUnsignedBigInteger(divisor)).longValue();
        }
    }

    /**
     * 返回第一个参数除以第二个参数的无符号余数，其中每个参数和结果都被解释为无符号值。
     *
     * @param dividend 被除数
     * @param divisor 除数
     * @return 第一个参数除以第二个参数的无符号余数
     * @see #divideUnsigned
     * @since 1.8
     */
    public static long remainderUnsigned(long dividend, long divisor) {
        if (dividend > 0 && divisor > 0) { // signed comparisons
            return dividend % divisor;
        } else {
            if (compareUnsigned(dividend, divisor) < 0) // Avoid explicit check for 0 divisor
                return dividend;
            else
                return toUnsignedBigInteger(dividend).
                    remainder(toUnsignedBigInteger(divisor)).longValue();
        }
    }

    // Bit Twiddling

    /**
     * 用于以二进制补码形式表示 {@code long} 值的位数。
     *
     * @since 1.5
     */
    @Native public static final int SIZE = 64;

    /**
     * 用于以二进制补码形式表示 {@code long} 值的字节数。
     *
     * @since 1.8
     */
    public static final int BYTES = SIZE / Byte.SIZE;

    /**
     * 返回一个最多只有一个1位的 {@code long} 值，位于指定 {@code long} 值中
     * 最高位（"最左边"）1位的位置。如果指定值在其二进制补码表示中没有1位，
     * 即等于零，则返回零。
     *
     * @param i 要计算其最高1位的值
     * @return 一个只有一个1位的 {@code long} 值，位于指定值中最高位1位的位置，
     *     如果指定值本身等于零，则返回零。
     * @since 1.5
     */
    public static long highestOneBit(long i) {
        // HD, Figure 3-1
        i |= (i >>  1);
        i |= (i >>  2);
        i |= (i >>  4);
        i |= (i >>  8);
        i |= (i >> 16);
        i |= (i >> 32);
        return i - (i >>> 1);
    }

    /**
     * 返回一个最多只有一个1位的 {@code long} 值，位于指定 {@code long} 值中
     * 最低位（"最右边"）1位的位置。如果指定值在其二进制补码表示中没有1位，
     * 即等于零，则返回零。
     *
     * @param i 要计算其最低1位的值
     * @return 一个只有一个1位的 {@code long} 值，位于指定值中最低位1位的位置，
     *     如果指定值本身等于零，则返回零。
     * @since 1.5
     */
    public static long lowestOneBit(long i) {
        // HD, Section 2-1
        return i & -i;
    }

    /**
     * 返回指定 {@code long} 值的二进制补码表示中最高位（"最左边"）1位之前的零位数。
     * 如果指定值在其二进制补码表示中没有1位，换句话说，如果它等于零，则返回64。
     *
     * <p>请注意，此方法与以2为底的对数密切相关。
     * 对于所有正的 {@code long} 值 x：
     * <ul>
     * <li>floor(log<sub>2</sub>(x)) = {@code 63 - numberOfLeadingZeros(x)}
     * <li>ceil(log<sub>2</sub>(x)) = {@code 64 - numberOfLeadingZeros(x - 1)}
     * </ul>
     *
     * @param i 要计算其前导零数的值
     * @return 指定 {@code long} 值的二进制补码表示中最高位（"最左边"）1位之前的零位数，
     *     如果值等于零，则返回64。
     * @since 1.5
     */
    public static int numberOfLeadingZeros(long i) {
        // HD, Figure 5-6
         if (i == 0)
            return 64;
        int n = 1;
        int x = (int)(i >>> 32);
        if (x == 0) { n += 32; x = (int)i; }
        if (x >>> 16 == 0) { n += 16; x <<= 16; }
        if (x >>> 24 == 0) { n +=  8; x <<=  8; }
        if (x >>> 28 == 0) { n +=  4; x <<=  4; }
        if (x >>> 30 == 0) { n +=  2; x <<=  2; }
        n -= x >>> 31;
        return n;
    }

    /**
     * 返回指定 {@code long} 值的二进制补码表示中最低位（"最右边"）1位之后的零位数。
     * 如果指定值在其二进制补码表示中没有1位，换句话说，如果它等于零，则返回64。
     *
     * @param i 要计算其尾随零数的值
     * @return 指定 {@code long} 值的二进制补码表示中最低位（"最右边"）1位之后的零位数，
     *     如果值等于零，则返回64。
     * @since 1.5
     */
    public static int numberOfTrailingZeros(long i) {
        // HD, Figure 5-14
        int x, y;
        if (i == 0) return 64;
        int n = 63;
        y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32);
        y = x <<16; if (y != 0) { n = n -16; x = y; }
        y = x << 8; if (y != 0) { n = n - 8; x = y; }
        y = x << 4; if (y != 0) { n = n - 4; x = y; }
        y = x << 2; if (y != 0) { n = n - 2; x = y; }
        return n - ((x << 1) >>> 31);
    }

    /**
     * 返回指定 {@code long} 值的二进制补码表示中1位的数量。
     * 此函数有时被称为<i>人口计数</i>。
     *
     * @param i 要计算其位数的值
     * @return 指定 {@code long} 值的二进制补码表示中1位的数量。
     * @since 1.5
     */
     public static int bitCount(long i) {
        // HD, Figure 5-14
        i = i - ((i >>> 1) & 0x5555555555555555L);
        i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
        i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
        i = i + (i >>> 8);
        i = i + (i >>> 16);
        i = i + (i >>> 32);
        return (int)i & 0x7f;
     }

    /**
     * 返回通过将指定 {@code long} 值的二进制补码表示向左旋转指定位数而获得的值。
     * （从左侧或高位移出的位重新进入右侧或低位。）
     *
     * <p>请注意，负距离的左旋转等同于右旋转：
     * {@code rotateLeft(val, -distance) == rotateRight(val, distance)}。
     * 还要注意，任何64的倍数的旋转都是无操作，因此除了旋转距离的最后六位之外，
     * 所有位都可以忽略，即使距离为负数：
     * {@code rotateLeft(val, distance) == rotateLeft(val, distance & 0x3F)}。
     *
     * @param i 要向左旋转其位的值
     * @param distance 向左旋转的位位置数
     * @return 通过将指定 {@code long} 值的二进制补码表示向左旋转指定位数而获得的值。
     * @since 1.5
     */
    public static long rotateLeft(long i, int distance) {
        return (i << distance) | (i >>> -distance);
    }

    /**
     * 返回通过将指定 {@code long} 值的二进制补码表示向右旋转指定位数而获得的值。
     * （从右侧或低位移出的位重新进入左侧或高位。）
     *
     * <p>请注意，负距离的右旋转等同于左旋转：
     * {@code rotateRight(val, -distance) == rotateLeft(val, distance)}。
     * 还要注意，任何64的倍数的旋转都是无操作，因此除了旋转距离的最后六位之外，
     * 所有位都可以忽略，即使距离为负数：
     * {@code rotateRight(val, distance) == rotateRight(val, distance & 0x3F)}。
     *
     * @param i 要向右旋转其位的值
     * @param distance 向右旋转的位位置数
     * @return 通过将指定 {@code long} 值的二进制补码表示向右旋转指定位数而获得的值。
     * @since 1.5
     */
    public static long rotateRight(long i, int distance) {
        return (i >>> distance) | (i << -distance);
    }

    /**
     * 返回通过颠倒指定 {@code long} 值的二进制补码表示中位的顺序而获得的值。
     *
     * @param i 要颠倒的值
     * @return 通过颠倒指定 {@code long} 值中位的顺序而获得的值。
     * @since 1.5
     */
    public static long reverse(long i) {
        // HD, Figure 7-1
        i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
        i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
        i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
        i = (i << 48) | ((i & 0xffff0000L) << 16) |
            ((i >>> 16) & 0xffff0000L) | (i >>> 48);
        return i;
    }

    /**
     * 返回指定 {@code long} 值的符号函数。（如果指定值为负数，则返回值为-1；
     * 如果指定值为零，则返回0；如果指定值为正数，则返回1。）
     *
     * @param i 要计算其符号的值
     * @return 指定 {@code long} 值的符号函数。
     * @since 1.5
     */
    public static int signum(long i) {
        // HD, Section 2-7
        return (int) ((i >> 63) | (-i >>> 63));
    }

    /**
     * 返回通过颠倒指定 {@code long} 值的二进制补码表示中字节顺序而获得的值。
     *
     * @param i 要颠倒其字节的值
     * @return 通过颠倒指定 {@code long} 值中字节而获得的值。
     * @since 1.5
     */
    public static long reverseBytes(long i) {
        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
        return (i << 48) | ((i & 0xffff0000L) << 16) |
            ((i >>> 16) & 0xffff0000L) | (i >>> 48);
    }

    /**
     * 按照 + 运算符将两个 {@code long} 值相加。
     *
     * @param a 第一个操作数
     * @param b 第二个操作数
     * @return {@code a} 和 {@code b} 的和
     * @see java.util.function.BinaryOperator
     * @since 1.8
     */
    public static long sum(long a, long b) {
        return a + b;
    }

    /**
     * 返回两个 {@code long} 值中较大的一个，
     * 就像调用 {@link Math#max(long, long) Math.max} 一样。
     *
     * @param a 第一个操作数
     * @param b 第二个操作数
     * @return {@code a} 和 {@code b} 中较大的一个
     * @see java.util.function.BinaryOperator
     * @since 1.8
     */
    public static long max(long a, long b) {
        return Math.max(a, b);
    }

    /**
     * 返回两个 {@code long} 值中较小的一个，
     * 就像调用 {@link Math#min(long, long) Math.min} 一样。
     *
     * @param a 第一个操作数
     * @param b 第二个操作数
     * @return {@code a} 和 {@code b} 中较小的一个
     * @see java.util.function.BinaryOperator
     * @since 1.8
     */
    public static long min(long a, long b) {
        return Math.min(a, b);
    }

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    @Native private static final long serialVersionUID = 4290774380558885855L;
}
